﻿using System.Linq;
using CodeCamp.Entities01;
using e1 = CodeCamp.Entities01;
using CodeCamp.Entities02;
using e2 = CodeCamp.Entities02;

namespace CodeCamp.Controllers
{
  public class CodeCampDataRepository
  {
    private CodeCampData01DataContext context01 = new CodeCampData01DataContext();
    private CodeCampData02DataContext context02 = new CodeCampData02DataContext();

    #region Events

    public IQueryable<e1.Event> GetEvents()
    { return context01.Events; }

    public e1.Event GetEvent( int eventId )
    { return context01.Events.FirstOrDefault( e => e.Id == eventId ); }

    public e1.Event GetEvent( string shortName )
    { return context01.Events.FirstOrDefault( e => e.ShortName == shortName ); }

    #endregion

    #region Sessions

    public IQueryable<e1.Session> GetSessions( int eventId )
    { return context01.Sessions.Where( s => s.EventId == eventId ); }

    public e1.Session GetSession( int sessionId )
    { return context01.Sessions.FirstOrDefault( s => s.Id == sessionId ); }

    public void Add( e1.Session session )
    { context01.Sessions.InsertOnSubmit( session ); }

    public void Delete( e1.Session session )
    { context01.Sessions.DeleteOnSubmit( session ); }

    #endregion

    #region ScheduledSession

    public ScheduledSession GetScheduledSession( int sessionId )
    {
      var session = context02.Sessions.Where( s => s.Id == sessionId ).FirstOrDefault();
      if ( session == null )
        return null;

      return session.ScheduledSessions.FirstOrDefault();
    }

    #endregion

    #region Timeslots

    public IQueryable<Timeslot> GetTimeslots( int eventId )
    { 
      return context02.Timeslots
        .Where( t => t.EventId == eventId )
        .OrderBy( t => t.Date )
        .ThenBy( t => t.StartTime );
    }

    #endregion

    #region Buildings

    internal IQueryable<Building> GetBuildings( int eventId )
    { return context02.Buildings.Where( b => b.EventId == eventId ); }

    #endregion

    #region Rooms

    internal Room GetRoom( int roomId )
    { return context02.Rooms.Where( room => room.Id == roomId ).FirstOrDefault(); } 

    #endregion

    #region Presenters

    public IQueryable<e1.Presenter> GetPresenters( int eventId )
    { return context01.Presenters.Where( p => p.EventId == eventId ); }

    public e1.Presenter GetPresenter( int presenterId )
    { return context01.Presenters.FirstOrDefault( p => p.Id == presenterId ); }

    public e1.Presenter GetPresenter( int eventId, string userIdentityName )
    { return context01.Presenters.FirstOrDefault( p => (p.EventId == eventId) && (p.UserIdentityName == userIdentityName) ); }

    public void Add( e1.Presenter presenter )
    { context01.Presenters.InsertOnSubmit( presenter ); }

    public void Delete( e1.Presenter presenter )
    { context01.Presenters.DeleteOnSubmit( presenter ); }

    #endregion

    #region SessionPresenters

    public void Add( e1.SessionPresenter sessionPresenter )
    { context01.SessionPresenters.InsertOnSubmit( sessionPresenter ); }

    #endregion

    #region Tags

    public IQueryable<Tag> GetTags( int eventId )
    { return context01.Tags.Where( t => t.EventId == eventId ).OrderBy( t => t.Name ); }

    public Tag GetTag( int tagId )
    { return context01.Tags.Where( t => t.Id == tagId ).FirstOrDefault(); }

    public Tag GetTag( int eventId, string tagName )
    { return context01.Tags.Where( t => (t.EventId == eventId) && (t.Name == tagName) ).FirstOrDefault(); }

    public void Add( Tag tag )
    { context01.Tags.InsertOnSubmit( tag ); }

    #endregion

    #region SessionTags

    public IQueryable<SessionTag> GetSessionTags( int sessionId )
    { return context01.SessionTags.Where( st => st.SessionId == sessionId ); }

    public void Add( SessionTag sessionTag )
    { context01.SessionTags.InsertOnSubmit( sessionTag ); }

    public void Delete( SessionTag sessionTag )
    { context01.SessionTags.DeleteOnSubmit( sessionTag ); }
    
    #endregion

    //#region Attendees

    //public Attendee GetAttendee( int eventId, string name )
    //{ return context02.Attendees.FirstOrDefault( a => (a.EventId == eventId) && (a.Name == name) ); }

    //public Attendee GetAttendee( int id )
    //{ return context02.Attendees.FirstOrDefault( a => a.Id == id ); }

    //private Attendee CreateAttendee( int eventId, string name, bool isAnonymous )
    //{
    //  var attendee = new Attendee { EventId = eventId, Name = name, IsAnonymous = isAnonymous };
    //  context02.Attendees.InsertOnSubmit( attendee );
    //  context02.SubmitChanges();

    //  return attendee;
    //}

    //public Attendee CreateAttendee( int eventId, string name )
    //{ return CreateAttendee( eventId, name, false ); } // create non-anonymous attendee

    //public Attendee CreateAnonymousAttendee( int eventId )
    //{
    //  var attendee = CreateAttendee( eventId, string.Empty, true ); // create anonymous attendee

    //  // rename attendee as AnonymousN where N = Id
    //  attendee.Name = string.Format( "Anonymous{0}", attendee.Id );
    //  context02.SubmitChanges();

    //  return attendee;
    //}

    //public void Add( Attendee attendee )
    //{ context02.Attendees.InsertOnSubmit( attendee ); }

    //#endregion

    //#region AttendeeSessionPicks

    //public void Add( AttendeeSessionPick attendeeSessionPick )
    //{ context02.AttendeeSessionPicks.InsertOnSubmit( attendeeSessionPick ); }

    //public void Delete( AttendeeSessionPick attendeeSessionPick )
    //{ context02.AttendeeSessionPicks.DeleteOnSubmit( attendeeSessionPick ); }

    //#endregion

    #region SpeakerRate

    public SpeakerRateSpeaker GetSpeakerRateSpeaker( int presenterId )
    { return context01.SpeakerRateSpeakers.FirstOrDefault( s => s.PresenterId == presenterId ); }

    public void Add( SpeakerRateSpeaker speakerRateSpeaker )
    { context01.SpeakerRateSpeakers.InsertOnSubmit( speakerRateSpeaker ); }

    public void Delete( SpeakerRateSpeaker speakerRateSpeaker )
    { context01.SpeakerRateSpeakers.DeleteOnSubmit( speakerRateSpeaker ); }

    #endregion

    #region Sponsors

    public IQueryable<Sponsor> GetSponsors( int eventId )
    { return context01.Sponsors.Where( s => s.EventId == eventId ); }

    public Sponsor GetSponsor( int sponsorId )
    { return context01.Sponsors.FirstOrDefault( s => s.Id == sponsorId ); }

    public void Add( Sponsor sponsor )
    { context01.Sponsors.InsertOnSubmit( sponsor ); }

    #endregion

    #region CommunitySponsor

    public IQueryable<CommunitySponsor> GetCommunitySponsors( int eventId )
    {
      return
        from s in context01.CommunitySponsors
        where s.EventId == eventId
        orderby s.Name
        select s;
    }

    #endregion

    #region IndividualContributor

    public IQueryable<IndividualContributor> GetIndividualContributors( int eventId )
    {
      return
        from s in context01.IndividualContributors
        where s.EventId == eventId
        orderby s.LastName
        select s;
    }

    #endregion

    #region Volunteers

    public IQueryable<Task> GetTasks( int eventId )
    { return 
        from t in context01.Tasks
        where t.EventId == eventId
        orderby t.Tasks_Timeslots.First().TaskTimeslot.Date, t.Tasks_Timeslots.First().TaskTimeslot.StartTime
        select t;
    }

    #endregion

    public void Save()
    {
      context01.SubmitChanges();
      context02.SubmitChanges();
    }

  }
}